﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Win32;

namespace LaserTag.Module.AForgeModule.Services
{
    public class HslConfiguration : IHslConfiguration
    {
        public HslConfiguration()
        {
            Load();
        }

        private int m_hueMinimum = 0;
        private int m_hueMaximum = 359;

        private double m_luminanceMinimum = 0;
        private double m_luminanceMaximum = 1;

        private double m_saturationMinimum = 0;
        private double m_saturationMaximum = 1;
        

        #region IHslConfiguration Members

        /// <summary>
        /// The minimum hue.  The range is 0 to 359.
        /// </summary>
        public int HueMinimum
        {
            get { return m_hueMinimum; }
            set { m_hueMinimum = value; }
        }

        /// <summary>
        /// The max hue.  The range is 0 to 359.
        /// </summary>
        public int HueMaximum
        {
            get { return m_hueMaximum; }
            set { m_hueMaximum = value; }
        }

        /// <summary>
        /// The minimum saturation. The range is 0 to 1.
        /// </summary>
        public double SaturationMinimum
        {
            get { return m_saturationMinimum; }
            set { m_saturationMinimum = value; }
        }


        public double SaturationMaximum
        {
            get { return m_saturationMaximum; }
            set { m_saturationMaximum = value; }
        }


        public double LuminanceMinimum
        {
            get { return m_luminanceMinimum; }
            set { m_luminanceMinimum = value; }
        }


        public double LuminanceMaximum
        {
            get { return m_luminanceMaximum; }
            set { m_luminanceMaximum = value; }
        }

        public void Save()
        {
            SaveRegistryValue(REG_KEY, "HueMinimum", HueMinimum);
            SaveRegistryValue(REG_KEY, "HueMaximum", HueMaximum);
            SaveRegistryValue(REG_KEY, "SaturationMinimum", SaturationMinimum);
            SaveRegistryValue(REG_KEY, "SaturationMaximum", SaturationMaximum);
            SaveRegistryValue(REG_KEY, "LuminanceMinimum", LuminanceMinimum);
            SaveRegistryValue(REG_KEY, "LuminanceMaximum", LuminanceMaximum);
        }

        private const string REG_KEY = @"Software\LaserTag";

        private void Load()
        {
            int? intVal = GetRegistryValue<int>(REG_KEY, "HueMinimum");
            if (intVal != null)
                HueMinimum = intVal.Value;

            intVal = GetRegistryValue<int>(REG_KEY, "HueMaximum");
            if (intVal != null)
                HueMaximum = intVal.Value;

            double? doubleVal = GetRegistryValueDouble(REG_KEY, "SaturationMinimum");
            if (doubleVal != null)
                SaturationMinimum = doubleVal.Value;

            doubleVal = GetRegistryValueDouble(REG_KEY, "SaturationMaximum");
            if (doubleVal != null)
                SaturationMaximum = doubleVal.Value;

            doubleVal = GetRegistryValueDouble(REG_KEY, "LuminanceMinimum");
            if (doubleVal != null)
                LuminanceMinimum = doubleVal.Value;

            doubleVal = GetRegistryValueDouble(REG_KEY, "LuminanceMaximum");
            if (doubleVal != null)
                LuminanceMaximum = doubleVal.Value;

        }

        private void SaveRegistryValue<T>(string keyPath, string valueName, T val) where T: struct
        {
            RegistryKey key = Registry.CurrentUser.OpenSubKey(keyPath, true);
            
            if(key == null)
                Registry.CurrentUser.CreateSubKey(keyPath);

            key.SetValue(valueName, val);

            key.Close();
        }

        private double? GetRegistryValueDouble(string keyPath, string valueName)
        {
            RegistryKey key = Registry.CurrentUser.OpenSubKey(keyPath);

            if (key != null)
            {
                object keyValue = key.GetValue(valueName);
                if (keyValue != null && keyValue is string && !string.IsNullOrEmpty((string)keyValue))
                {
                    key.Close();
                    return double.Parse((string)keyValue);
                }
            }

            return null;
        }

        private T? GetRegistryValue<T>(string keyPath, string valueName) where T : struct
        {
            RegistryKey key = Registry.CurrentUser.OpenSubKey(keyPath);

            if (key != null)
            {
                object keyValue = key.GetValue(valueName);
                if (keyValue != null)
                {
                    key.Close();
                    return (T)keyValue;
                }
            }

            return default(T);
        }

        #endregion
    }
}
